package basic

import (
	"errors"
	"fmt"
	os2 "os"
)

// 资源管理和出错处理
// 资源管理通过defer来管理的，确保在函数结束发生 这是栈后进先出 最后的defer先执行
// 即便函数遇见return panic 也会先执行defer
// defer 如果里面使用到外边变量 那么用的是一开那个值后面即便改了也没用
// 何时使用 defer Open/close Lock/unLock printHeader/PrintFooter 打印最终报告 db

func writeFile(filename string) {
	f, err := os2.Create(filename)
	if err != nil {
		// panic(err)
	}
	defer f.Close()

	// 先往内存里面写 写完了在刷到硬盘上
	//writer := bufio.NewWriter(f)
	//fmt.Fprintln(writer, "aa")
	//writer.Flush()
}

func Expection() {
	fmt.Println("Expection")

	writeFile("")

	//for i := 0; i < 100; i++ {
	//	defer fmt.Println(i) // 31 ... 0
	//	if i > 30 {
	//		panic("")
	//	}
	//}
	// error 的处理 panic 直接挂掉程序 error级别轻点可控的用error
	var err error = errors.New("errors")
	var deferr error = nil
	fmt.Println(err.Error(), deferr)

	//fs,es := os2.OpenFile("", os2.O_APPEND, 0666)
	//if pathError,ok := es.(*os2.PathError);ok{panic}else{} 直接如果有错panic 不知道出现这个问题怎么处理

	// panic 遇到错误是在不知道怎么玩才用这个，否则都建议返回error来搞起来
	// 停止当前函数的执行
	// 一直向上返回，执行每一层的defer最后退出程序，除了 http 服务器 http服务器有自己的保护，如果没有遇见recover就退出
	// recover会组织panic的错误

	//// recover 它可以获取panic的值 如果无法处理继续panic
	//// 仅仅在 defer中调用
	//defer func() {
	//	e := recover() // 如果不是error的类型直接在仍错误panic传入也建议errors.New
	//	if err, ok := e.(error); ok { // 这里在加一种 userError 的断言 如果是这个类型用 Msg   实现随意定一个类型 type userError string 类型方法实现Msg 和 Error接口方法就得了
	//		fmt.Println(err)
	//	} else {
	//		panic(err)
	//	}
	//}()
	//
	////panic(errors.New("23"))

	// 自定义错误消息
	//type userError interface {
	//	error
	//	Msg() string
	//}
}
